package com.wendy.monitor.config;

import com.wendy.common.core.constant.SecurityConstants;
import de.codecentric.boot.admin.server.config.AdminServerProperties;
import de.codecentric.boot.admin.server.web.client.HttpHeadersProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpHeaders;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;

/**
 * 监控权限配置
 * 
 * @author wendy
 */
@EnableWebSecurity
public class WebSecurityConfigurer
{
    private final String adminContextPath;

    public WebSecurityConfigurer(AdminServerProperties adminServerProperties)
    {
        this.adminContextPath = adminServerProperties.getContextPath();
    }

    /**
     * 配置安全过滤链
     *
     * @param httpSecurity 用于配置HTTP安全性的对象
     * @return 返回配置好的SecurityFilterChain对象
     * @throws Exception 如果配置过程中发生错误，则抛出异常
     */
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception
    {
        // 创建并配置AuthenticationSuccessHandler，用于定义用户成功登录后重定向的逻辑
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter("redirectTo");
        successHandler.setDefaultTargetUrl(adminContextPath + "/");

        // 配置HTTP安全设置，包括headers、authorizeRequests、formLogin、logout和httpBasic
        return httpSecurity
                .headers().frameOptions().disable() // 允许iframe嵌套
                .and().authorizeRequests()
                .antMatchers(adminContextPath + "/assets/**" // 对静态资源和登录页面等不进行认证
                        , adminContextPath + "/login"
                        , adminContextPath + "/actuator/**"
                        , adminContextPath + "/instances/**"
                ).permitAll()
                .anyRequest().authenticated() // 其他所有请求需要认证
                .and()
                .formLogin().loginPage(adminContextPath + "/login") // 配置登录页面
                .successHandler(successHandler).and() // 设置登录成功后的处理
                .logout().logoutUrl(adminContextPath + "/logout") // 配置登出URL
                .and()
                .httpBasic().and() // 配置HTTP基本认证
                .csrf().disable() // 禁用跨站请求伪造(CSRF)保护
                .build();
    }


    /**
     * 创建一个自定义的HttpHeadersProvider Bean。
     * 这个函数不接受任何参数。
     * 这个方法用户标识这个请求为健康检查
     * @return HttpHeadersProvider 一个函数式接口，返回HttpHeaders实例。
     *         这个HttpHeaders实例被配置了特定的请求头。
     */
    @Bean
    public HttpHeadersProvider customHttpHeadersProvider() {
        // 为每个请求生成并返回一个包含固定请求头的HttpHeaders实例
        return instance -> {
            HttpHeaders httpHeaders = new HttpHeaders();
            // 添加一个指定来源的请求头
            httpHeaders.add(SecurityConstants.FROM_SOURCE, SecurityConstants.HEALTH);
            return httpHeaders;
        };
    }


}
